/*
 * Copyright (c) 2024 Huawei Device Co., Ltd.
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#ifndef OH_INPUT_MANAGER_H
#define OH_INPUT_MANAGER_H

/**
 * @addtogroup input
 * @{
 *
 * @brief 提供多模态输入域的C接口。
 *
 * @since 12
 */

/**
 * @file oh_input_manager.h
 *
 * @brief 提供事件注入和关键状态查询等功能。
 *
 * @syscap SystemCapability.MultimodalInput.Input.Core
 * @library liboh_input.so
 * @since 12
 */

#include <stdint.h>

#include "oh_key_code.h"

#ifdef __cplusplus
extern "C" {
#endif

/**
 * @brief 按键状态的枚举值。
 *
 * @since 12
 */
typedef enum Input_KeyStateAction {
    /** 默认状态 */
    KEY_DEFAULT = -1,
    /** 按键按下 */
    KEY_PRESSED = 0,
    /** 按键抬起 */
    KEY_RELEASED = 1,
    /** 按键开关使能 */
    KEY_SWITCH_ON = 2,
    /** 按键开关去使能 */
    KEY_SWITCH_OFF = 3
} Input_KeyStateAction;

/**
 * @brief 按键事件类型的枚举值。
 *
 * @since 12
 */
typedef enum Input_KeyEventAction {
    /** 按键动作取消 */
    KEY_ACTION_CANCEL = 0,
    /** 按键按下 */
    KEY_ACTION_DOWN = 1,
    /** 按键抬起 */
    KEY_ACTION_UP = 2,
} Input_KeyEventAction;

/**
 * @brief 鼠标动作的枚举值
 *
 * @since 12
 */
typedef enum Input_MouseEventAction {
    /** 取消鼠标动作 */
    MOUSE_ACTION_CANCEL = 0,
    /** 移动鼠标 */
    MOUSE_ACTION_MOVE = 1,
    /** 按下鼠标 */
    MOUSE_ACTION_BUTTON_DOWN = 2,
    /** 抬起鼠标按键 */
    MOUSE_ACTION_BUTTON_UP = 3,
    /** 鼠标轴事件开始 */
    MOUSE_ACTION_AXIS_BEGIN = 4,
    /** 更新鼠标轴事件 */
    MOUSE_ACTION_AXIS_UPDATE = 5,
    /** 鼠标轴事件结束 */
    MOUSE_ACTION_AXIS_END = 6,
} Input_MouseEventAction;

/**
 * @brief 鼠标轴事件类型
 *
 * @since 12
 */
typedef enum InputEvent_MouseAxis {
    /** 垂直滚动轴 */
    MOUSE_AXIS_SCROLL_VERTICAL = 0,
    /** 水平滚动轴 */
    MOUSE_AXIS_SCROLL_HORIZONTAL = 1,
} InputEvent_MouseAxis;

/**
 * @brief 鼠标按键的枚举值。
 *
 * @since 12
 */
typedef enum Input_MouseEventButton {
    /** 无效按键 */
    MOUSE_BUTTON_NONE = -1,
    /** 鼠标左键 */
    MOUSE_BUTTON_LEFT = 0,
    /** 鼠标中间键 */
    MOUSE_BUTTON_MIDDLE = 1,
    /** 鼠标右键 */
    MOUSE_BUTTON_RIGHT = 2,
    /** 鼠标前进键 */
    MOUSE_BUTTON_FORWARD = 3,
    /** 鼠标返回键 */
    MOUSE_BUTTON_BACK = 4,
} Input_MouseEventButton;

/**
 * @brief 触摸动作的枚举值。
 *
 * @since 12
 */
typedef enum Input_TouchEventAction {
    /** 触摸取消 */
    TOUCH_ACTION_CANCEL = 0,
    /** 触摸按下 */
    TOUCH_ACTION_DOWN = 1,
    /** 触摸移动 */
    TOUCH_ACTION_MOVE = 2,
    /** 触摸抬起 */
    TOUCH_ACTION_UP = 3,
} Input_TouchEventAction;

/**
 * @brief 定义按键信息，用于标识按键行为。例如，“Ctrl”按键信息包含键值和键类型。
 *
 * @since 12
 */
struct Input_KeyState;

/**
 * @brief 要注入的按键事件
 *
 * @since 12
 */
struct Input_KeyEvent;

/**
 * @brief 要注入的鼠标事件
 *
 * @since 12
 */
struct Input_MouseEvent;

/**
 * @brief 要注入的触摸事件
 *
 * @since 12
 */
struct Input_TouchEvent;

/**
 * @brief 错误码枚举值
 *
 * @since 12
 */
typedef enum Input_Result {
    /** 操作成功 */
    INPUT_SUCCESS = 0,
    /** 权限验证失败 */
    INPUT_PERMISSION_DENIED = 201,
    /** 非系统应用 */
    INPUT_NOT_SYSTEM_APPLICATION = 202,
    /** 参数检查失败 */
    INPUT_PARAMETER_ERROR = 401
} Input_Result;

/**
 * @brief 查询按键状态的枚举对象。
 *
 * @param keyState 按键状态的枚举对象，具体请参考{@Link Input_KeyStateAction}
 *
 * @return 如果操作成功，@return返回{@Link Input_Result#INPUT_SUCCESS}; 
 * 否则返回{@Link Input_Result}中定义的其他错误代码。
 * @syscap SystemCapability.MultimodalInput.Input.Core
 * @since 12
 */
Input_Result OH_Input_GetKeyState(struct Input_KeyState* keyState);

/**
 * @brief 创建按键状态的枚举对象。
 *
 * @return 如果操作成功，@return返回一个{@link Input_KeyState}指针对象
 * 否则返回空指针。
 * @syscap SystemCapability.MultimodalInput.Input.Core
 * @since 12
 */
struct Input_KeyState* OH_Input_CreateKeyState();

/**
 * @brief 销毁按键状态的枚举对象。
 *
 * @param keyState 按键状态的枚举对象，具体请参考{@Link Input_KeyStateAction}
 * @syscap SystemCapability.MultimodalInput.Input.Core
 * @since 12
 */
void OH_Input_DestroyKeyState(struct Input_KeyState** keyState);

/**
 * @brief 设置按键状态对象的键值。
 *
 * @param keyState 按键状态的枚举对象，具体请参考{@Link Input_KeyStateAction}
 * @param keyCode 按键键值。
 * @syscap SystemCapability.MultimodalInput.Input.Core
 * @since 12
 */
void OH_Input_SetKeyCode(struct Input_KeyState* keyState, int32_t keyCode);

/**
 * @brief 获取按键状态对象的键值。
 * 
 * @param keyState 按键状态的枚举对象，具体请参考{@Link Input_KeyStateAction}
 * @return 返回按键状态对象的键值。
 * @syscap SystemCapability.MultimodalInput.Input.Core
 * @since 12
 */
int32_t OH_Input_GetKeyCode(const struct Input_KeyState* keyState);

/**
 * @brief 设置按键状态对象的按键是否按下。
 * 
 * @param keyState 按键状态的枚举对象，具体请参考{@Link Input_KeyStateAction}
 * @param keyAction 按键是否按下，具体请参考{@Link Input_KeyEventAction}
 * @syscap SystemCapability.MultimodalInput.Input.Core
 * @since 12
 */
void OH_Input_SetKeyPressed(struct Input_KeyState* keyState, int32_t keyAction);

/**
 * @brief 获取按键状态对象的按键是否按下。
 * 
 * @param keyState 按键状态的枚举对象，具体请参考{@Link Input_KeyStateAction}
 * @return 返回按键状态对象的按键按下状态。
 * @syscap SystemCapability.MultimodalInput.Input.Core
 * @since 12
 */
int32_t OH_Input_GetKeyPressed(const struct Input_KeyState* keyState);

/**
 * @brief 设置按键状态对象的按键开关。
 * 
 * @param keyState 按键状态的枚举对象，具体请参考{@Link Input_KeyStateAction}
 * @param keySwitch 按键开关。
 * @syscap SystemCapability.MultimodalInput.Input.Core
 * @since 12
 */
void OH_Input_SetKeySwitch(struct Input_KeyState* keyState, int32_t keySwitch);

/**
 * @brief 获取按键状态对象的按键开关。
 * 
 * @param keyState 按键状态的枚举对象，具体请参考{@Link Input_KeyStateAction}
 * @return 返回按键状态对象的按键开关。
 * @syscap SystemCapability.MultimodalInput.Input.Core
 * @since 12
 */
int32_t OH_Input_GetKeySwitch(const struct Input_KeyState* keyState);

/**
 * @brief 注入按键事件
 *
 * @param keyEvent - 要注入的按键事件
 * @return 0 - 成功
 *         201 - 缺少权限
 *         401 - 参数错误
 * @syscap SystemCapability.MultimodalInput.Input.Core
 * @since 12
 */
int32_t OH_Input_InjectKeyEvent(const struct Input_KeyEvent* keyEvent);

/**
 * @brief 创建按键事件对象
 *
 * @return 如果操作成功返回一个{@link Input_KeyEvent}指针对象
 * 否则返回空指针。
 * @syscap SystemCapability.MultimodalInput.Input.Core
 * @since 12
 */
struct Input_KeyEvent* OH_Input_CreateKeyEvent();

/**
 * @brief 销毁按键事件对象
 *
 * @param keyEvent 按键事件对象
 * @syscap SystemCapability.MultimodalInput.Input.Core
 * @since 12
 */
void OH_Input_DestroyKeyEvent(struct Input_KeyEvent** keyEvent);

/**
 * @brief 设置按键事件类型
 *
 * @param keyEvent 按键事件对象
 * @param action 按键事件类型
 * @syscap SystemCapability.MultimodalInput.Input.Core
 * @since 12
 */
void OH_Input_SetKeyEventAction(struct Input_KeyEvent* keyEvent, int32_t action);

/**
 * @brief 获取按键事件类型
 *
 * @param keyEvent 按键事件对象
 * @return 返回按键事件类型
 * @syscap SystemCapability.MultimodalInput.Input.Core
 * @since 12
 */
int32_t OH_Input_GetKeyEventAction(const struct Input_KeyEvent* keyEvent);

/**
 * @brief 设置按键事件的键值
 *
 * @param keyEvent 按键事件对象
 * @param keyCode 按键的键值
 * @syscap SystemCapability.MultimodalInput.Input.Core
 * @since 12
 */
void OH_Input_SetKeyEventKeyCode(struct Input_KeyEvent* keyEvent, int32_t keyCode);

/**
 * @brief 获取按键事件的键值
 *
 * @param keyEvent 按键事件对象
 * @return Key code.
 * @syscap SystemCapability.MultimodalInput.Input.Core
 * @since 12
 */
int32_t OH_Input_GetKeyEventKeyCode(const struct Input_KeyEvent* keyEvent);

/**
 * @brief 设置按键事件发生的时间
 *
 * @param keyEvent 按键事件对象
 * @param actionTime 按键事件发生的时间
 * @syscap SystemCapability.MultimodalInput.Input.Core
 * @since 12
 */
void OH_Input_SetKeyEventActionTime(struct Input_KeyEvent* keyEvent, int64_t actionTime);

/**
 * @brief 获取按键事件发生的时间
 *
 * @param keyEvent 按键事件对象
 * @return 返回按键事件发生的时间
 * @syscap SystemCapability.MultimodalInput.Input.Core
 * @since 12
 */
int64_t OH_Input_GetKeyEventActionTime(const struct Input_KeyEvent* keyEvent);

/**
 * @brief 注入鼠标事件
 *
 * @param mouseEvent - 要注入的鼠标事件
 * @return 0 - 成功
 *         201 - 缺少权限
 *         401 - 参数错误
 * @syscap SystemCapability.MultimodalInput.Input.Core
 * @since 12
 */
int32_t OH_Input_InjectMouseEvent(const struct Input_MouseEvent* mouseEvent);

/**
 * @brief 创建鼠标事件对象
 *
 * @return 如果操作成功返回一个{@link Input_MouseEvent}指针对象
 * 否则返回空指针。
 * @syscap SystemCapability.MultimodalInput.Input.Core
 * @since 12
 */
struct Input_MouseEvent* OH_Input_CreateMouseEvent();

/**
 * @brief 销毁鼠标事件对象
 *
 * @param mouseEvent 鼠标事件对象
 * @syscap SystemCapability.MultimodalInput.Input.Core
 * @since 12
 */
void OH_Input_DestroyMouseEvent(struct Input_MouseEvent** mouseEvent);

/**
 * @brief 设置鼠标事件的动作
 *
 * @param mouseEvent 鼠标事件对象
 * @param action 鼠标的动作
 * @syscap SystemCapability.MultimodalInput.Input.Core
 * @since 12
 */
void OH_Input_SetMouseEventAction(struct Input_MouseEvent* mouseEvent, int32_t action);

/**
 * @brief 获取鼠标事件的动作
 *
 * @param mouseEvent 鼠标事件对象
 * @return 鼠标的动作
 * @syscap SystemCapability.MultimodalInput.Input.Core
 * @since 12
 */
int32_t OH_Input_GetMouseEventAction(const struct Input_MouseEvent* mouseEvent);

/**
 * @brief 设置鼠标事件的屏幕横坐标
 *
 * @param mouseEvent 鼠标事件对象
 * @param displayX 屏幕横坐标
 * @syscap SystemCapability.MultimodalInput.Input.Core
 * @since 12
 */
void OH_Input_SetMouseEventDisplayX(struct Input_MouseEvent* mouseEvent, int32_t displayX);

/**
 * @brief 获取鼠标事件的屏幕横坐标
 *
 * @param mouseEvent 鼠标事件对象
 * @return 屏幕横坐标
 * @syscap SystemCapability.MultimodalInput.Input.Core
 * @since 12
 */
int32_t OH_Input_GetMouseEventDisplayX(const struct Input_MouseEvent* mouseEvent);

/**
 * @brief 设置鼠标事件的屏幕纵坐标
 *
 * @param mouseEvent 鼠标事件对象
 * @param displayY 屏幕纵坐标
 * @syscap SystemCapability.MultimodalInput.Input.Core
 * @since 12
 */
void OH_Input_SetMouseEventDisplayY(struct Input_MouseEvent* mouseEvent, int32_t displayY);

/**
 * @brief 获取鼠标事件的屏幕纵坐标
 *
 * @param mouseEvent 鼠标事件对象
 * @return 屏幕纵坐标
 * @syscap SystemCapability.MultimodalInput.Input.Core
 * @since 12
 */
int32_t OH_Input_GetMouseEventDisplayY(const struct Input_MouseEvent* mouseEvent);

/**
 * @brief 设置鼠标事件的按键
 *
 * @param mouseEvent 鼠标事件对象
 * @param button 鼠标按键
 * @syscap SystemCapability.MultimodalInput.Input.Core
 * @since 12
 */
void OH_Input_SetMouseEventButton(struct Input_MouseEvent* mouseEvent, int32_t button);

/**
 * @brief 获取鼠标事件的按键
 *
 * @param mouseEvent 鼠标事件对象
 * @return 鼠标按键
 * @syscap SystemCapability.MultimodalInput.Input.Core
 * @since 12
 */
int32_t OH_Input_GetMouseEventButton(const struct Input_MouseEvent* mouseEvent);

/**
 * @brief 设置鼠标轴事件的类型
 *
 * @param mouseEvent 鼠标事件对象
 * @param axisType 轴类型，比如垂直轴、水平轴。
 * @syscap SystemCapability.MultimodalInput.Input.Core
 * @since 12
 */
void OH_Input_SetMouseEventAxisType(struct Input_MouseEvent* mouseEvent, int32_t axisType);

/**
 * @brief 获取鼠标轴事件的类型
 *
 * @param mouseEvent 鼠标事件对象
 * @return 轴类型
 * @syscap SystemCapability.MultimodalInput.Input.Core
 * @since 12
 */
int32_t OH_Input_GetMouseEventAxisType(const struct Input_MouseEvent* mouseEvent);

/**
 * @brief 设置鼠标轴事件的值
 *
 * @param mouseEvent 鼠标事件对象
 * @param axisType 轴事件的值，正数向前滚动，负数向后滚动。
 * @syscap SystemCapability.MultimodalInput.Input.Core
 * @since 12
 */
void OH_Input_SetMouseEventAxisValue(struct Input_MouseEvent* mouseEvent, float axisValue);

/**
 * @brief 获取鼠标轴事件的值
 *
 * @param mouseEvent 鼠标事件对象
 * @return 轴事件的值
 * @syscap SystemCapability.MultimodalInput.Input.Core
 * @since 12
 */
float OH_Input_GetMouseEventAxisValue(const struct Input_MouseEvent* mouseEvent);

/**
 * @brief 设置鼠标事件发生的时间
 *
 * @param mouseEvent 鼠标事件对象
 * @param actionTime 鼠标事件发生的时间
 * @syscap SystemCapability.MultimodalInput.Input.Core
 * @since 12
 */
void OH_Input_SetMouseEventActionTime(struct Input_MouseEvent* mouseEvent, int64_t actionTime);

/**
 * @brief 获取鼠标事件发生的时间
 *
 * @param keyEvent 鼠标事件对象
 * @return 返回鼠标事件发生的时间
 * @syscap SystemCapability.MultimodalInput.Input.Core
 * @since 12
 */
int64_t OH_Input_GetMouseEventActionTime(const struct Input_MouseEvent* mouseEvent);

/**
 * @brief 注入触摸事件
 *
 * @param touchEvent - 要注入的触摸事件
 * @return 0 - 成功
 *         201 - 缺少权限
 *         401 - 参数错误
 * @syscap SystemCapability.MultimodalInput.Input.Core
 * @since 12
 */
int32_t OH_Input_InjectTouchEvent(const struct Input_TouchEvent* touchEvent);

/**
 * @brief 创建触屏事件对象
 *
 * @return 如果操作成功返回一个{@link Input_TouchEvent}指针对象
 * 否则返回空指针。
 * @syscap SystemCapability.MultimodalInput.Input.Core
 * @since 12
 */
struct Input_TouchEvent* OH_Input_CreateTouchEvent();

/**
 * @brief 销毁触屏事件对象
 *
 * @param touchEvent 触屏事件对象
 * @syscap SystemCapability.MultimodalInput.Input.Core
 * @since 12
 */
void OH_Input_DestroyTouchEvent(struct Input_TouchEvent** touchEvent);

/**
 * @brief 设置触屏事件的动作
 *
 * @param touchEvent 触屏事件对象
 * @param 触屏的动作
 * @syscap SystemCapability.MultimodalInput.Input.Core
 * @since 12
 */
void OH_Input_SetTouchEventAction(struct Input_TouchEvent* touchEvent, int32_t action);

/**
 * @brief 获取触屏事件的动作
 *
 * @param touchEvent 触屏事件对象
 * @return 触屏的动作
 * @syscap SystemCapability.MultimodalInput.Input.Core
 * @since 12
 */
int32_t OH_Input_GetTouchEventAction(const struct Input_TouchEvent* touchEvent);

/**
 * @brief 设置触屏事件的手指ID
 *
 * @param touchEvent 触屏事件对象
 * @param id 触屏的手指ID
 * @syscap SystemCapability.MultimodalInput.Input.Core
 * @since 12
 */
void OH_Input_SetTouchEventFingerId(struct Input_TouchEvent* touchEvent, int32_t id);

/**
 * @brief 获取触屏事件的手指ID
 *
 * @param touchEvent 触屏事件对象
 * @return 触屏的手指ID
 * @syscap SystemCapability.MultimodalInput.Input.Core
 * @since 12
 */
int32_t OH_Input_GetTouchEventFingerId(const struct Input_TouchEvent* touchEvent);

/**
 * @brief 设置触屏事件的屏幕横坐标
 *
 * @param touchEvent 触屏事件对象
 * @param 触屏的屏幕横坐标
 * @syscap SystemCapability.MultimodalInput.Input.Core
 * @since 12
 */
void OH_Input_SetTouchEventDisplayX(struct Input_TouchEvent* touchEvent, int32_t displayX);

/**
 * @brief 获取触屏事件的屏幕横坐标
 *
 * @param touchEvent 触屏事件对象
 * @return 触屏的屏幕横坐标
 * @syscap SystemCapability.MultimodalInput.Input.Core
 * @since 12
 */
int32_t OH_Input_GetTouchEventDisplayX(const struct Input_TouchEvent* touchEvent);

/**
 * @brief 设置触屏事件的屏幕纵坐标
 *
 * @param touchEvent 触屏事件对象
 * @param 触屏的屏幕纵坐标
 * @syscap SystemCapability.MultimodalInput.Input.Core
 * @since 12
 */
void OH_Input_SetTouchEventDisplayY(struct Input_TouchEvent* touchEvent, int32_t displayY);

/**
 * @brief 获取触屏事件的屏幕纵坐标
 *
 * @param touchEvent 触屏事件对象
 * @return 触屏的屏幕纵坐标
 * @syscap SystemCapability.MultimodalInput.Input.Core
 * @since 12
 */
int32_t OH_Input_GetTouchEventDisplayY(const struct Input_TouchEvent* touchEvent);

/**
 * @brief 设置触摸事件发生的时间
 *
 * @param keyEvent 触屏事件对象
 * @param actionTime 触摸事件发生的时间
 * @syscap SystemCapability.MultimodalInput.Input.Core
 * @since 12
 */
void OH_Input_SetTouchEventActionTime(struct Input_TouchEvent* touchEvent, int64_t actionTime);

/**
 * @brief 获取触摸事件发生的时间
 *
 * @param keyEvent 触屏事件对象
 * @return 返回触摸事件发生的时间
 * @syscap SystemCapability.MultimodalInput.Input.Core
 * @since 12
 */
int64_t OH_Input_GetTouchEventActionTime(const struct Input_TouchEvent* touchEvent);

/**
 * @brief 取消事件注入并撤销授权
 *
 * @syscap SystemCapability.MultimodalInput.Input.Core
 * @since 12
 */
void OH_Input_CancelInjection();

#ifdef __cplusplus
}
#endif
/** @} */

#endif /* OH_INPUT_MANAGER_H */